package org.zjx.action.game;

import org.zjx.analysis.window.NpcDialogueAnalysis;
import org.zjx.core.IWindow;
import org.zjx.entity.ParagraphBean;

import java.awt.*;
import java.util.List;

public class DialogueAction extends AbstractWindowAction {
    private NpcDialogueAnalysis dialogueAnalysis;
    private final List<String> dialogueContent;

    public DialogueAction(IWindow targetWindow, List<String> dialogueContent) {
        super(targetWindow,true);
        this.dialogueContent = dialogueContent;
    }

    private void analysis() {
        dialogueAnalysis = new NpcDialogueAnalysis(targetWindow, stateManager.getGameState().getScreenshot());
    }


    @Override
    public void open() {

    }

    @Override
    public void close() {
        analysis();
        if (!dialogueAnalysis.isOpened()) return;
        click(dialogueAnalysis.getCloseButtonPoint());
        delay(300);
        flush();
        close();
    }

    @Override
    public void reSetWindow() {

    }

    @Override
    public void mouseAloofWindow(Rectangle rect) {
        if (dialogueAnalysis.mouseInRect(rect)) {
            Point safePoint = dialogueAnalysis.findLargestRemainingAreaCenter(rect);
            move(safePoint);
            analysis();
        }
    }

    @Override
    protected void doExecute() throws Exception {
        analysis();
        mouseAloofWindow(dialogueAnalysis.windowArea == null? dialogueAnalysis.getOriginBounds(): dialogueAnalysis.windowArea);
        if (dialogueContent == null || dialogueContent.isEmpty()) {
            close();
            return;
        }

        int currentButtonIndex = 0;
        int maxAttempts = 15; // 防止无限循环


        while (dialogueAnalysis.isOpened() && currentButtonIndex < dialogueContent.size() && maxAttempts-- > 0) {
            analysis();
            List<ParagraphBean.Word> buttons = dialogueAnalysis.getWordList();
            if (buttons == null || buttons.isEmpty()) {
                //点击中间跳页
                clickNextPage(dialogueAnalysis.conversion(dialogueAnalysis.windowArea, dialogueAnalysis.getContentArea()));
                continue;
            }

            // 检查是否有后续按钮能匹配（包括当前按钮）
            int foundIndex = findNextMatchIndex(currentButtonIndex, buttons);
            if (foundIndex == -1) {
                clickNextPage(dialogueAnalysis.conversion(dialogueAnalysis.windowArea, dialogueAnalysis.getContentArea()));
                continue;
            }

            // 如果找到的是后续按钮（说明当前按钮缺失）
            if (foundIndex > currentButtonIndex) {
                currentButtonIndex = foundIndex; // 直接跳到找到的按钮
            }

            // 点击找到的按钮
            ParagraphBean.Word word = buttons.stream()
                    .filter(w -> isMatch(dialogueContent.get(foundIndex), w.getName()))
                    .findFirst().orElse(null);
            if (word != null) {
                click(word.getRectangle());
                delay(300);
                currentButtonIndex++;
            }
        }

        if (!dialogueAnalysis.isOpened()){
            close();
        }
        delay(500);
    }

    private int findNextMatchIndex(int startIndex, List<ParagraphBean.Word> buttons) {
        for (int i = startIndex; i < dialogueContent.size(); i++) {
            String target = normalizeText(dialogueContent.get(i));
            for (ParagraphBean.Word word : buttons) {
                if (isMatch(target, word.getName())) {
                    return i; // 返回第一个匹配的按钮索引
                }
            }
        }
        return -1;
    }

    private boolean isMatch(String target, String buttonText) {
        return isOrderedContains(normalizeText(target), normalizeText(buttonText));
    }

    private String normalizeText(String text) {
        return text.replace(",", "").replace("，", "").trim();
    }

    private void clickNextPage(Rectangle contentRect) {
        click(contentRect);
        delay(500);
    }

    /**
     * 检查 s1 是否按顺序包含 s2 的所有字符（不要求连续）
     * @param s1 源字符串
     * @param s2 目标字符串
     * @return true - s1 按顺序包含 s2 的所有字符；false - 不包含或顺序不一致
     */
    private boolean isOrderedContains(String s1, String s2) {
        // 处理边界情况
        if (s2 == null || s2.isEmpty()) {
            return true; // 空字符串总是被包含
        }
        if (s1 == null || s1.isEmpty()) {
            return false; // s1为空但s2非空时，不包含
        }

        int index = 0; // 当前在s1中的查找起始位置
        for (char c : s2.toCharArray()) {
            // 从当前index开始查找字符c
            int pos = s1.indexOf(c, index);
            if (pos == -1) {
                return false; // 未找到字符
            }
            index = pos + 1; // 更新查找起始位置为找到位置的下一位
        }
        return true; // 所有字符均按顺序找到
    }
}
